//
//  KLMSigScanManager.swift
//  KLM
//
//  Created by 朱雨 on 2023/6/7.
//

import Foundation
import CoreBluetooth
import nRFMeshProvision

class KLMSigScanManager: NSObject {
    
    static let shared = KLMSigScanManager()
    private override init(){}
    
    var command: KLMSigMeshCommand?
    
    private lazy var centralManager: CBCentralManager = {
        let centralManager = CBCentralManager()
        centralManager.delegate = self
        return centralManager
    }()
    
    ///开始扫描
    func startScan(scanDevice: @escaping ScanDevice, commandResult: @escaping CommandResult) {
        
        let command = KLMSigMeshCommand()
        command.scanDevice = scanDevice
        command.commandResult = commandResult
        command.timeout = 20
        self.command = command
        command.startTimer { [weak self] error in
            guard let self = self else { return }
            ///停止扫描
            stopScanning()
            //超时返回失败
            DispatchQueue.main.async {
                commandResult(false, error)
            }
        }
        startScanning()
    }
    
    private func startScanning() {
        centralManager.scanForPeripherals(withServices: [MeshProvisioningService.uuid],
                                          options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
    }
    
    func stopScanning() {
        KLMLog("停止扫描")
        centralManager.stopScan()
        command?.commandResponseFinishWithCommand()
        command = nil
    }
    
    ///停止扫描时间
    func stopScanTimer() {
        command?.commandResponseFinishWithCommand()
    }
}

extension KLMSigScanManager: CBCentralManagerDelegate {

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            startScanning()
        } else {
            KLMLog("Central is not powered on")
            if central.state == .unauthorized {
                //弹框
                KLMBlueToothManager.showUnauthorizedAlert()
            }
        }
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
                        advertisementData: [String : Any], rssi RSSI: NSNumber) {
        if let unprovisionedDevice = UnprovisionedDevice(advertisementData: advertisementData) {

            //过滤一下设备
            if unprovisionedDevice.uuid.uuidString.count >= 2 {
                //以DD开头的设备是我们的
                let id = Int(unprovisionedDevice.uuid.uuid.0).decimalTo2Hexadecimal()
                let index = Int(unprovisionedDevice.uuid.uuid.1).decimalTo2Hexadecimal()
                let type = nodeDeviceType.init(rawValue: index) ?? .meta1OneCamera
                ///针对客户定制区分颜色和角度
                let subIndex = unprovisionedDevice.uuid.uuid.9
                if id == "DD" {
                    var name = unprovisionedDevice.name
                    switch type {
                    case .qieXiang:
                        name = KLMLocalizable.LANGLOC("Phase-cut Controller")
                    case .RGBControl:
                        name = KLMLocalizable.LANGLOC("LED Strip Controller")
                    case .WWCW:
                        name = "步路思灯带"
                    case .Dali:
                        name = KLMLocalizable.LANGLOC("DALI 2 Controller")
                    case .danse,
                            .shuangse:
                        name = KLMLocalizable.LANGLOC("0/1-10V Controller")
                    case .meta1NoCamera,
                            .meta2NoCamera,
                            .meta2NoCameraC10:
                        name = "Track"
                    case .meta1OneCamera,
                            .meta2OneCamera:
                        name = "Track-1S"
                        
                    case .meta2TwoCamera:
                        name = "Track-2S"
                    case .gateway:
                        name = KLMLocalizable.LANGLOC("Gateway")
                    case .gatewayNew:
                        name = KLMLocalizable.LANGLOC("Gateway")
                    case .scene1:
                        name = KLMLocalizable.LANGLOC("1 Gang self-powered scene switch")
                    case .scene2:
                        name = KLMLocalizable.LANGLOC("2 Gang self-powered scene switch")
                    case .scene3:
                        name = KLMLocalizable.LANGLOC("3 Gang self-powered scene switch")
                    case .singleFire1:
                        name = KLMLocalizable.LANGLOC("1 Gang smart wall switch")
                    case .singleFire2:
                        name = KLMLocalizable.LANGLOC("2 Gang smart wall switch")
                    case .singleFire3:
                        name = KLMLocalizable.LANGLOC("3 Gang smart wall switch")
                    case .metaG2NoCamera:
                        name = "MetaG2"
                    case .metaG2OneCamera:
                        name = "MetaG2-1S"
                    case .metaG2TwoCamera:
                        name = "MetaG2-2S"
                    case .embeddedSceneController:
                        name = "嵌入式场景识别控制器"
                    case .meta2FreshNo,
                            .meta2FreshC10:
                        name = "生鲜灯"
                    case .meta2FreshOne:
                        name = "生鲜灯-1S"
                    case .meta2FreshTwo:
                        name = "生鲜灯-2S"
                    case .metaUniOne:
                        name = "MetaUni-1S"
                    case .metaUniTwo:
                        name = "MetaUni-2S"
                    case .metaUniNo:
                        name = "MetaUni"
                    case .lunaWWCW:
                        name = "LunaUni"
                    case .lunaWRGB,
                            .lunaWW:
                        name = "Luna"
                    case .RKAllInOne:
                        name = KLMLocalizable.LANGLOC("Smart Space Sensor")
                    case .MusesOneCamera:
                        name = "Sara-1S"
                    case .MusesTwoCamera:
                        name = "Sara-2S"
                    case .lukaNoCamera:
                        name = "Luka"
                    case .lukaOneCamera:
                        name = "Luka-1S"
                    case .lukaUniOneCamera:
                        name = "LukaUni-1S"
                    case .auraUniNoCamera:
                        name = "AuraUni"
                    case .auraUniOneCamera:
                        name = "AuraUni-1S"
                    case .kanoOneCamera:
                        name = "Kano-1S"
                    case .kanoTwoCamera:
                        name = "Kano-2S"
                    case .tableLamp:
                        name = KLMLocalizable.LANGLOC("Desk lamp")
                    case .lineLamp:
                        name = KLMLocalizable.LANGLOC("Line lamp")
                    case .Accelerometer:
                        name = "加速计"
                    case .wallLamp:
                        name = "Halo-1S"
                    case .kanoUniOneCamera:
                        name = "KanoUni-1S"
                    case .kanoUniTwoCamera:
                        name = "KanoUni-2S"
                    default:
                        break
                    }
                    unprovisionedDevice.name = name
                    var rssi: RssiLevel = .none
                    switch RSSI.intValue {
                    case -128:
                        rssi = .none
                    case -127 ..< -80:
                        rssi = .one
                    case -80 ..< -70:
                        rssi = .two
                    case -70 ..< -40:
                        rssi = .three
                    default:
                        rssi = .four
                    }
                    
                    let discoveredPeripheral: DiscoveredPeripheral = DiscoveredPeripheral(device: unprovisionedDevice, peripheral: peripheral, deviceType: type, Rssi: rssi)
                    if let scanBlock = command?.scanDevice {
                        DispatchQueue.main.async {
                            scanBlock(discoveredPeripheral)
                        }
                    }
                }
            }
        }
    }
}
